/****************************************************
	文件：IteratorPattern.cs
	作者：HuskyT
	邮箱：1005240602@qq.com
	日期：2020/5/10 9:57:31
	功能：迭代器模式
*****************************************************/

using System.Collections.Generic;
using UnityEngine;

namespace DesignPatterns
{
    public class IteratorPattern : MonoBehaviour
    {
        private void Start()
        {
            //迭代器模式：
            //对于聚合对象（对象集合），在不暴露其内部数据结构的情况下，遍历其中元素
            //将 遍历元素的方法 从聚合对象中分离出来
            //便于扩展多种遍历方式
            AggregateBase<string> aggregate = new ConcreteAggregate<string>();
            aggregate[0] = "L";
            aggregate[1] = "O";
            aggregate[2] = "V";
            aggregate[3] = "E";
            //顺序遍历
            IIterator<string> increase = aggregate.GetIterator(IteratorType.Increace);
            do
            {
                Debug.Log(increase.Current());
            } while (increase.MoveNext());

            //倒序遍历
            IIterator<string> decrease = aggregate.GetIterator(IteratorType.Decreace);
            do
            {
                Debug.Log(decrease.Current());
            } while (decrease.MoveNext());
        }

        /// <summary>
        /// 聚合基类
        /// </summary>
        public abstract class AggregateBase<T>
        {
            protected List<T> mArray;
            public AggregateBase()
            {
                mArray = new List<T>();
            }
            /// <summary>
            /// 获取迭代器
            /// </summary>
            public abstract IIterator<T> GetIterator(IteratorType iteratorType);
            /// <summary>
            /// 实现索引器
            /// </summary>
            public T this[int index]
            {
                get
                {
                    if (index > mArray.Count - 1 || index < 0) return default;
                    return mArray[index];
                }
                set { mArray.Insert(index, value); }
            }
            public int Count => mArray.Count;
        }
        /// <summary>
        /// 聚合类（实现）
        /// </summary>
        public class ConcreteAggregate<T> : AggregateBase<T>
        {
            public override IIterator<T> GetIterator(IteratorType iteratorType)
            {
                switch (iteratorType)
                {
                    case IteratorType.Increace:
                        return new IteratorIncrease<T>(this);
                    case IteratorType.Decreace:
                        return new IteratorDecrease<T>(this);
                    default:
                        return null;
                }
            }
        }

        /// <summary>
        /// 迭代器接口
        /// </summary>
        public interface IIterator<T>
        {
            /// <summary>
            /// 获取当前元素
            /// </summary>
            T Current();
            /// <summary>
            /// 移动到下一元素
            /// </summary>
            bool MoveNext();
            /// <summary>
            /// 重置
            /// </summary>
            void Reset();
        }
        /// <summary>
        /// 升序的迭代器
        /// </summary>
        public class IteratorIncrease<T> : IIterator<T>
        {
            private int mCurrent;
            private ConcreteAggregate<T> mAggregate;

            public IteratorIncrease(ConcreteAggregate<T> aggreate)
            {
                mAggregate = aggreate;
                mCurrent = 0;
            }

            public T Current()
            {
                return mAggregate[mCurrent];
            }
            public bool MoveNext()
            {
                if (mAggregate[mCurrent + 1] != default)
                {
                    mCurrent++;
                    return true;
                }
                return false;
            }
            public void Reset()
            {
                mCurrent = 0;
            }
        }
        /// <summary>
        /// 降序的迭代器
        /// </summary>
        public class IteratorDecrease<T> : IIterator<T>
        {
            private int mCurrent;
            private ConcreteAggregate<T> mAggregate;

            public IteratorDecrease(ConcreteAggregate<T> aggreate)
            {
                mAggregate = aggreate;
                mCurrent = mAggregate.Count - 1;
            }

            public T Current()
            {
                return mAggregate[mCurrent];
            }
            public bool MoveNext()
            {
                if (mAggregate[mCurrent - 1] != default)
                {
                    mCurrent--;
                    return true;
                }
                return false;
            }
            public void Reset()
            {
                mCurrent = mAggregate.Count - 1;
            }
        }
        /// <summary>
        /// 迭代器类型
        /// </summary>
        public enum IteratorType
        {
            Increace,
            Decreace,
        }
    }
}